﻿using System;
using System.Linq.Expressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Sundstrom.Mvvm.Tests.ViewModels
{
    [TestClass]
    public class ObservableObjectTest
    {
        [TestMethod]
        public void RaisePropertyChanged_Successful()
        {
            bool hasFired = false;
            string firedProperty = null;
            string firedPropertyValue = null;

            var obj = new TestObservableObject();
            obj.PropertyChanged += (s, e) =>
            {
                hasFired = true;
                firedProperty = e.PropertyName;
                firedPropertyValue = obj.TestProperty;
            };
            obj.TestProperty = "Robert";

            Assert.IsTrue(hasFired);
            Assert.IsTrue(firedProperty == "TestProperty");
            Assert.IsTrue(firedPropertyValue == "Robert");
        }

        [TestMethod]
        public void RaisePropertyChangedWithExpression_Successful()
        {
            var obj = new TestObservableObject();
            obj.TestRaisePropertyChanged(() => obj.TestProperty);
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentException))]
        public void RaisePropertyChangedWithExpression_ArgumentException_NotAMember()
        {
            var obj = new TestObservableObject();
            obj.TestRaisePropertyChanged(() => Prop);
        }

        public int Prop { get; set; }
    }

    public class TestObservableObject : ObservableObject
    {
        private string _testProperty;

        public string TestProperty
        {
            set
            {
                _testProperty = value;
                RaisePropertyChanged(() => TestProperty);
            }

            get { return _testProperty; }
        }

        public void TestRaisePropertyChanged<TProperty>(Expression<Func<TProperty>> propertyExpression)
        {
            base.RaisePropertyChanged(propertyExpression);
        }
    }
}